#include <stdio.h>
#include <stdlib.h>

#include "mylist.h"
#include "myqueue.h"
#include "mystack.h"

Queue create_input_queue(int inNumOfElements,int inNumOfZero);
void display_input_queue(Queue inQueue1,Queue inQueue2,int inNumOfElements);
Queue create_result_queue(Queue inQueue1,Queue inQueue2,int inNumOfElements);
void display_queue(Queue inQueue);
void check_duplicat_values(Stack inStack,Queue inQueue,int inComparValue,int inNumRecurrence);

int main() 
{
	int iChoice=0,iNumElements=0,iNumElements1=0,iNumElements2=0,iNumOfZero=0,i,count;
	int *pData;
	Queue qQueue1,qQueue2,qResult;
	Stack sStack;

	printf("****************************************************************\n");
	printf("      Exercise 2			\n");
	printf("							\n");
	printf("      Oren Attia			\n");
	printf("      ID:29074333			\n");
	printf("							\n");
	printf("      Computer Science		\n"); 
	printf("							\n");
	printf("****************************************************************\n");

	while(iChoice!=3)
	{
		printf("1. Exercise 1 \n");
		printf("2. Exercise 2 \n");
		printf("3. EXIT\n");
		printf("Enter your choice : ");
		scanf("%d",&iChoice);
		switch(iChoice)
			{
				case 1 :
					{
						printf("Enter Number of Elements for Queue 1 : ");
						scanf("%d",&iNumElements1);
						printf("\n");
						printf("Enter Number of Elements for Queue 2 : ");
						scanf("%d",&iNumElements2);
						printf("\n\n");

						if(iNumElements1 == iNumElements2)
						{
							printf("Elements for Queue 1 : \n");
							qQueue1=create_input_queue(iNumElements1,0);
							printf("Elements for Queue 2 : \n");
							qQueue2=create_input_queue(iNumElements2,0);
						}
						else
							if(iNumElements1 < iNumElements2)
							{
								iNumOfZero=(iNumElements2-iNumElements1);
								printf("Elements for Queue 1 : \n");
								qQueue1=create_input_queue(iNumElements1,iNumOfZero);
								printf("Elements for Queue 2 : \n");
								qQueue2=create_input_queue(iNumElements2,0);	
							}
							else
							{
								iNumOfZero=(iNumElements1-iNumElements2);
								printf("Elements for Queue 1 : \n");
								qQueue1=create_input_queue(iNumElements1,0);
								printf("Elements for Queue 2 : \n");
								qQueue2=create_input_queue(iNumElements2,iNumOfZero);	
							}

						if(iNumElements1>iNumElements2)
							iNumElements=iNumElements1;
						else
							iNumElements=iNumElements2;
						display_input_queue(qQueue1,qQueue2,iNumElements);

						printf("\n\n");

						qResult=create_result_queue(qQueue1,qQueue2,iNumElements);
						display_queue(qResult);

						printf("\n\n");

					break;
					}			
				case 2 :
					{
						printf("Enter Number of Elements for Given Queue : ");
						scanf("%d",&iNumElements);
						printf("\n");
				
						qQueue1=create_input_queue(iNumElements,0);

						printf("\n\n");

						display_queue(qQueue1,iNumElements);

						printf("\n\n");
				
						sStack=initStack();
						pData=dequeue(qQueue1);
						check_duplicat_values(sStack,qQueue1,*pData,1);

					break;
					}
				case 3 :
					exit(0);
				default:
					{
						printf("Invalid choice\n");
						getch();
					break;
					}
			}
		getch();
	}
return 0;
}

Queue create_input_queue(int inNumOfElements,int inNumOfZero)
{
	Queue tmpQ,tmpQReturn;
	int   *tmpData,tmpNum=0,i,tmpDisplayNum=0,tmpCumulator=1 ;

	tmpQ=initQueue();
	tmpQReturn=initQueue();

	for(i=0;i<inNumOfZero;i++) 
	{
		if((tmpData=(int *)malloc(sizeof(int))) == NULL)
			return NULL;

		*tmpData=0;
		enqueue(tmpQ,tmpData);
	}

	for(i=0;i<inNumOfElements;i++)
	{
		if((tmpData=(int *)malloc(sizeof(int))) == NULL)
			return NULL;
	
		printf("Enter Digit {0-9} - No[%2d]",i);
		scanf("%d",&tmpNum);
		printf("\n");

		*tmpData=tmpNum;

		tmpDisplayNum+=(tmpCumulator*tmpNum);
		tmpCumulator=tmpCumulator*10;

		enqueue(tmpQ,tmpData);
	}

return tmpQ;
}

Queue create_result_queue(Queue inQueue1,Queue inQueue2,int inNumOfElements)
{
	Queue tmpQResult,tmpQReturn;
	int   *tmpQData1,*tmpQData2,*tmpSum,tmpTotal=0,tmpRemainder=0,i;

	tmpQResult=initQueue();
	tmpQReturn=initQueue();

	for(i=0;i<inNumOfElements;i++)
	{

		tmpQData1=dequeue(inQueue1);
		tmpQData2=dequeue(inQueue2);

		tmpTotal=(*tmpQData1 + *tmpQData2)%10 + tmpRemainder;
		if(tmpTotal>9)
		{
			tmpTotal=tmpTotal%10;
			tmpRemainder=1;
		}
		else
		{
			tmpRemainder=(*tmpQData1 + *tmpQData2)/10;
		}

		if((tmpSum=(int *)malloc(sizeof(int))) == NULL)
				return NULL;

		*tmpSum=tmpTotal;
		enqueue(tmpQResult,tmpSum);
	}

	if(tmpRemainder>0)
	{
		if((tmpSum=(int *)malloc(sizeof(int))) == NULL)
				return NULL;

		*tmpSum=tmpRemainder;
		enqueue(tmpQResult,tmpSum);
	}

	while(!isQueueEmpty(tmpQResult))
	{
		tmpQData1=dequeue(tmpQResult);
		enqueue(tmpQReturn,tmpQData1);
	}

return tmpQReturn;
}

void display_input_queue(Queue inQueue1,Queue inQueue2,int inNumOfElements)
{
	int i,*tmpElement1,*tmpElement2;
	Queue tmpQueue1,tmpQueue2;

	tmpQueue1=copyQueue(inQueue1,sizeof(int));
	tmpQueue2=copyQueue(inQueue2,sizeof(int));

	printf("Queue 1 \tQueue 2\n");
	printf("\n");
	printf("First   \tFirst \n");
	printf("------- \t-------\n");
	for(i=0;i<inNumOfElements;i++)
	{
		tmpElement1=dequeue(tmpQueue1);
		tmpElement2=dequeue(tmpQueue2);
		printf("|%3d|\t\t|%3d|\n",*tmpElement1,*tmpElement2);
	}
	printf("------- \t-------\n");
	printf("Last    \tLast \n");
}
void display_queue(Queue inQueue)
{
	int *tmpElement;
	Queue tmpQueue;

	tmpQueue=copyQueue(inQueue,sizeof(int));

	printf("Result Queue\n");
	printf("\n");
	printf("First\n");
	printf("-------\n");
	while(!isQueueEmpty(tmpQueue))
	{
		tmpElement=dequeue(tmpQueue);
		printf("|%3d|\n",*tmpElement);
	}
	printf("-------\n");
	printf("Last\n");
}

void check_duplicat_values(Stack inStack,Queue inQueue,int inComparValue,int inNumRecurrence)
{
	Stack tmpS;
	Queue tmpQ;
	int   *tmpDataQ,*tmpDataS;

	tmpS=initStack();
	tmpQ=initQueue();

	while(!isQueueEmpty(inQueue))
	{
		tmpDataQ=dequeue(inQueue);
		if(*tmpDataQ != inComparValue)
		{
			enqueue(tmpQ,tmpDataQ);
		}
		else
		{
			inNumRecurrence++;
		}
	}
	
	while(!isQueueEmpty(tmpQ))
	{
		if((tmpDataS=(int *)malloc(sizeof(int))) == NULL)
			return NULL;

		*tmpDataS=(inComparValue * inNumRecurrence);
		Push(tmpS,tmpDataS);

		printf("  %d   ",*tmpDataS);

		tmpDataS=dequeue(tmpQ);

		check_duplicat_values(tmpS,tmpQ,*tmpDataS,1);
	}

return ;
}